package com.example.tiantian.process;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.example.tiantian.BaseActivity;
import com.example.tiantian.R;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;

public class ProcessCleanerActivity extends BaseActivity
        implements Runnable, Callback, OnClickListener, OnItemClickListener {

    TextView txtCount;
    TextView txtMemory;
    ListView list;
    Button btnAll;
    Button btnChange;
    Button btnHidden;
    Button btnClean;

    ActivityManager activityManager;
    PackageManager PackManger;

    List<RunningAppProcessInfo> allList;
    List<RunningAppProcessInfo> userList;
    List<RunningAppProcessInfo> sysList;

    Set<RunningAppProcessInfo> checked;

    FrameLayout layoutLoad;

    Handler handler;

    ProcessAdapter adapter;

    boolean onlyUser = false;
    boolean isRun = true;

    @Override
    protected void init() {
        setContentView(R.layout.activity_process_cleaner);

        txtCount = (TextView) findViewById(R.id.process_cleaner_count);
        txtMemory = (TextView) findViewById(R.id.process_cleaner_memory);

        list = (ListView) findViewById(R.id.process_cleaner_list);
        btnAll = (Button) findViewById(R.id.process_cleaner_select_all);
        btnChange = (Button) findViewById(R.id.process_cleaner_select_change);
        btnHidden = (Button) findViewById(R.id.process_cleaner_hidden_system);
        btnClean = (Button) findViewById(R.id.process_cleaner_clean);

        layoutLoad = (FrameLayout) findViewById(R.id.process_cleaner_load);

        activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        PackManger = getPackageManager();

        userList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
        sysList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
        checked = new HashSet<ActivityManager.RunningAppProcessInfo>();

        handler = new Handler(this);
    }

    @Override
    protected void loadData() {
        load();
        new Thread(this).start();
    }

    @Override
    protected void event() {
        list.setOnItemClickListener(this);

        btnAll.setOnClickListener(this);
        btnChange.setOnClickListener(this);
        btnHidden.setOnClickListener(this);
        btnClean.setOnClickListener(this);
    }

    private void load() {
        new Thread() {
            public void run() {
                allList = activityManager.getRunningAppProcesses();
                userList.clear();
                sysList.clear();
                for (RunningAppProcessInfo r : allList) {
                    if (r.processName.equals("android.process.acore")
                            || r.processName.equals("android.process.media")) {
                        // 两个特殊的系统进程
                        sysList.add(r);
                    } else {
                        // 进程名称----》应用信息---》系统/用户
                        try {
                            ApplicationInfo app = PackManger.getApplicationInfo(r.processName, 0);
                            int flag = app.flags;// 包含了一些有关于应用类型的数据
                            if ((flag & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                                // 本是系统应用，但是升级之后，成了用户应用
                                userList.add(r);
                            } else if ((flag & ApplicationInfo.FLAG_SYSTEM) == 0) {
                                userList.add(r);// 非系统应用
                            } else {
                                sysList.add(r);
                            }
                        } catch (NameNotFoundException e) {
                            Log.e(getPackageName(), e.toString());
                        }
                    }
                }
                allList.clear();
                allList.addAll(sysList);
                allList.addAll(userList);

                Message msg = Message.obtain();
                msg.what = 1;
                handler.sendMessage(msg);

            };
        }.start();
    }

    @Override
    public void run() {

        while (isRun) {

            try {
                Thread.sleep(5000);
                handler.sendEmptyMessage(2);
            } catch (InterruptedException e) {
                Log.e(getPackageName(), e.toString());
            }
        }
    }

    // 获取可用内存
    public long getUseableMemory() {
        android.app.ActivityManager.MemoryInfo minfo = new android.app.ActivityManager.MemoryInfo();
        activityManager.getMemoryInfo(minfo);
        long size = minfo.availMem;
        return size;
    }

    // 获取总内存大小
    public long getTotalMemory() {
        String filename = "/proc/meminfo";
        String content = "";
        long total = 0;
        BufferedReader br;
        try {
            br = new BufferedReader(new FileReader(filename));
            content = br.readLine();
            total = Long.parseLong(content.substring(content.indexOf(":") + 1, content.indexOf("k")).trim());
            total *= 1024;
        } catch (FileNotFoundException e) {
            Log.e(getPackageName(), e.toString());
        } catch (IOException e) {
            Log.e(getPackageName(), e.toString());
        }

        return total;
    }

    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == 1) {
            layoutLoad.setVisibility(View.GONE);

            adapter = new ProcessAdapter(this, (onlyUser) ? allList : userList, checked, activityManager, PackManger);
            list.setAdapter(adapter);
        } else {
            txtCount.setText(getString(R.string.process_cleaner_count) + ":" + allList.size());
            long useable = getUseableMemory();
            long total = getTotalMemory();
            txtMemory.setText(getString(R.string.process_cleaner_memory) + ":"
                    + Formatter.formatFileSize(this, total - useable) + "/" + Formatter.formatFileSize(this, total));

        }
        return false;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // 获取这个选项对应的进程对象
        RunningAppProcessInfo r = (RunningAppProcessInfo) parent.getAdapter().getItem(position);

        if (r.processName.equals(getPackageName())) {
            return;
        }

        CheckBox cb = (CheckBox) view.findViewById(R.id.process_item_check);
        if (cb.isChecked()) {
            cb.setChecked(false);
            checked.remove(r);
        } else {
            cb.setChecked(true);
            checked.add(r);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.process_cleaner_hidden_system:
            adapter.setList((onlyUser) ? allList : userList);
            onlyUser = !onlyUser;
            break;
        case R.id.process_cleaner_select_all:
            checked.addAll(onlyUser ? userList : allList);
            checked.remove(getApplicationInfo());
            break;
        case R.id.process_cleaner_select_change:
            Set<RunningAppProcessInfo> temp = new HashSet<ActivityManager.RunningAppProcessInfo>();
            temp.addAll(checked);
            checked.clear();
            for (RunningAppProcessInfo r : (onlyUser ? userList : allList)) {
                if (temp.contains(r)) {
                    continue;
                }
                checked.add(r);
            }
            break;
        case R.id.process_cleaner_clean:
            if (checked.size() > 0) {
                for (RunningAppProcessInfo r : checked) {
                    activityManager.killBackgroundProcesses(r.processName);
                    sysList.remove(r);
                    userList.remove(r);
                    allList.remove(r);
                }
                checked.clear();
                layoutLoad.setVisibility(View.VISIBLE);
                load();
            }
            break;
        default:
            break;
        }
        adapter.notifyDataSetChanged();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        isRun = false;
    }
}
